import { NextRequest, NextResponse } from 'next/server';
import { GloableResponseItem, ResponseEnum } from '@/utils/request/res';
import { Auth, type ExtendedNextApiRequest, ResponseHandler, LogOperation } from '@/utils/decorator';
import prisma from '@/utils/db/PrismaService';
import { BaseController } from '@/utils/request/BaseController';
import { GET as HttpGet, POST as HttpPost, PUT as HttpPut, DELETE as HttpDelete } from '@/utils/decorator';
import { createAllMethodHandlers } from '@/utils/request/routeRegistry';
import { Prisma } from '@prisma/client';
import { getCurrentTimeInShanghai } from '@/utils/storage';
import crypto from 'crypto';

class SystemSettingController extends BaseController {
    
    /**
     * 获取系统配置列表
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getSettingList(request: ExtendedNextApiRequest) {
        try {
            const params: any = request.customBody;
            const { config_type, config_key, page = '1', pageSize = '10' } = params;
            
            const pageNum = parseInt(page);
            const size = parseInt(pageSize);
            const offset = (pageNum - 1) * size;
            
            // 构建查询条件
            let whereConditions = Prisma.sql`WHERE del_flag = 1`;
            
            if (config_type && config_type !== '') {
                whereConditions = Prisma.sql`${whereConditions} AND config_type = ${config_type}`;
            }
            
            if (config_key && config_key !== '') {
                whereConditions = Prisma.sql`${whereConditions} AND config_key LIKE ${`%${config_key}%`}`;
            }
            
            // 获取总数
            const countResult = await prisma.$queryRaw<{ count: BigInt }[]>(Prisma.sql`
                SELECT COUNT(*) as count
                FROM sys_setting
                ${whereConditions}
            `);
            const total = Number(countResult[0]?.count || 0);

            // 获取列表数据
            const list = await prisma.$queryRaw<any[]>(Prisma.sql`
                SELECT 
                    id, config_key, config_value, config_name, config_type,
                    description, is_encrypted, sort_order, create_time, update_time
                FROM sys_setting
                ${whereConditions}
                ORDER BY sort_order ASC, config_type ASC, id DESC
                LIMIT ${size} OFFSET ${offset}
            `);
            
            // 处理敏感配置数据
            const processedList = list.map((item: any) => ({
                ...item,
                id: Number(item.id),
                config_value: item.is_encrypted === 1 ? '***已加密***' : item.config_value
            }));
            
            return GloableResponseItem(ResponseEnum.success, "获取配置列表成功", {
                list: processedList,
                pagination: {
                    current: pageNum,
                    pageSize: size,
                    total
                }
            });
        } catch (error) {
            console.error('获取配置列表失败:', error);
            return GloableResponseItem(ResponseEnum.error, "获取配置列表失败", null);
        }
    }

    // 获取配置详情
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getSettingDetail(request: ExtendedNextApiRequest) {
        return GloableResponseItem(ResponseEnum.fail, "该接口暂未开放", null);
    }
    
    /**
     * 新增系统配置
     */
    @Auth()
    @ResponseHandler()
    @HttpPost()
    @LogOperation({
        module: "系统配置",
        operationName: "新增配置"
    })
    static async addSetting(request: ExtendedNextApiRequest) {
        try {
            const data = request.customBody;
            const {
                config_key,
                config_value,
                config_name,
                config_type,
                description,
                is_encrypted = 0,
                sort_order = 0
            } = data;
            
            if (!config_key || !config_name || !config_type) {
                return GloableResponseItem(ResponseEnum.fail, "配置键、配置名称和配置类型不能为空", null);
            }
            
            // 检查配置键是否已存在
            const existingSetting = await prisma.$queryRaw<any[]>(Prisma.sql`
                SELECT id FROM sys_setting 
                WHERE config_key = ${config_key} AND del_flag = 1
            `);
            
            if (existingSetting.length > 0) {
                return GloableResponseItem(ResponseEnum.fail, "配置键已存在", null);
            }
            
            let processedValue = config_value;
            
            // 如果需要加密
            if (is_encrypted === 1 && config_value) {
                processedValue = SystemSettingController.encryptValue(config_value);
            }
            
            const currentTime = getCurrentTimeInShanghai();
            
            // 插入新配置
            const result = await prisma.$executeRaw(Prisma.sql`
                INSERT INTO sys_setting (
                    config_key, config_value, config_name, config_type, 
                    description, is_encrypted, sort_order, create_time, update_time, del_flag
                ) VALUES (
                    ${config_key}, ${processedValue}, ${config_name}, ${config_type},
                    ${description || ''}, ${is_encrypted}, ${sort_order}, 
                    ${currentTime}, ${currentTime}, 1
                )
            `);
            
            return GloableResponseItem(ResponseEnum.success, "新增配置成功", { affected: result });
        } catch (error) {
            console.error('新增配置失败:', error);
            return GloableResponseItem(ResponseEnum.error, "新增配置失败", null);
        }
    }
    
    /**
     * 更新系统配置
     */
    @Auth()
    @ResponseHandler()
    @HttpPut()
    @LogOperation({
        module: "系统配置",
        operationName: "更新配置"
    })
    static async updateSetting(request: ExtendedNextApiRequest) {
        try {
            const data = request.customBody;
            const {
                id,
                config_value,
                config_name,
                config_type,
                description,
                is_encrypted,
                sort_order
            } = data;
            
            if (!id) {
                return GloableResponseItem(ResponseEnum.fail, "配置ID不能为空", null);
            }
            
            // 检查配置是否存在
            const existingSetting = await prisma.$queryRaw<any[]>(Prisma.sql`
                SELECT id, config_value, is_encrypted FROM sys_setting 
                WHERE id = ${parseInt(id)} AND del_flag = 1
            `);
            
            if (existingSetting.length === 0) {
                return GloableResponseItem(ResponseEnum.fail, "配置不存在", null);
            }
            
            let processedValue = config_value;
            
            // 处理加密逻辑
            if (is_encrypted === 1 && config_value && config_value !== '***已加密***') {
                processedValue = SystemSettingController.encryptValue(config_value);
            } else if (config_value === '***已加密***') {
                // 如果是加密标识，保持原值不变
                processedValue = existingSetting[0].config_value;
            }
            
            const currentTime = getCurrentTimeInShanghai();
            
            // 构建更新SQL
            const updates: string[] = [];
            const values: any[] = [];
            
            if (config_value !== undefined) {
                updates.push('config_value = ?');
                values.push(processedValue);
            }
            if (config_name !== undefined) {
                updates.push('config_name = ?');
                values.push(config_name);
            }
            if (config_type !== undefined) {
                updates.push('config_type = ?');
                values.push(config_type);
            }
            if (description !== undefined) {
                updates.push('description = ?');
                values.push(description);
            }
            if (is_encrypted !== undefined) {
                updates.push('is_encrypted = ?');
                values.push(is_encrypted);
            }
            if (sort_order !== undefined) {
                updates.push('sort_order = ?');
                values.push(sort_order);
            }
            
            updates.push('update_time = ?');
            values.push(currentTime);
            values.push(parseInt(id));
            
            const result = await prisma.$executeRaw(Prisma.sql`
                UPDATE sys_setting 
                SET config_value = ${processedValue}, 
                    config_name = ${config_name || existingSetting[0].config_name},
                    config_type = ${config_type || existingSetting[0].config_type},
                    description = ${description !== undefined ? description : existingSetting[0].description},
                    is_encrypted = ${is_encrypted !== undefined ? is_encrypted : existingSetting[0].is_encrypted},
                    sort_order = ${sort_order !== undefined ? sort_order : existingSetting[0].sort_order},
                    update_time = ${currentTime}
                WHERE id = ${parseInt(id)}
            `);
            
            return GloableResponseItem(ResponseEnum.success, "更新配置成功", { affected: result });
        } catch (error) {
            console.error('更新配置失败:', error);
            return GloableResponseItem(ResponseEnum.error, "更新配置失败", null);
        }
    }
    
    /**
     * 删除系统配置
     */
    @Auth()
    @ResponseHandler()
    @HttpDelete()
    @LogOperation({
        module: "系统配置",
        operationName: "删除配置"
    })
    static async deleteSetting(request: ExtendedNextApiRequest) {
        try {
            const data = request.customBody;
            const { ids } = data;
            
            if (!ids || !Array.isArray(ids) || ids.length === 0) {
                return GloableResponseItem(ResponseEnum.fail, "请选择要删除的配置", null);
            }
            
            const currentTime = getCurrentTimeInShanghai();
            const idList = ids.map((id: any) => parseInt(id));
            
            // 软删除配置
            let result = 0;
            for (const id of idList) {
                const affected = await prisma.$executeRaw(Prisma.sql`
                    UPDATE sys_setting 
                    SET del_flag = 0, update_time = ${currentTime}
                    WHERE id = ${id} AND del_flag = 1
                `);
                result += Number(affected);
            }
            
            return GloableResponseItem(ResponseEnum.success, "删除配置成功", { affected: result });
        } catch (error) {
            console.error('删除配置失败:', error);
            return GloableResponseItem(ResponseEnum.error, "删除配置失败", null);
        }
    }
    
    /**
     * 获取配置类型选项
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getSettingTypes(request: ExtendedNextApiRequest) {
        try {
            const types = [
                { value: 'system_basic', label: '系统基础配置' },
                { value: 'email', label: '邮件配置' },
                { value: 'sms', label: '短信配置' },
                { value: 'file_storage', label: '文件存储配置' },
                { value: 'security', label: '安全配置' },
                { value: 'interface', label: '接口配置' },
                { value: 'cache', label: '缓存配置' },
                { value: 'ui', label: '界面配置' }
            ];
            
            return GloableResponseItem(ResponseEnum.success, "获取配置类型成功", types);
        } catch (error) {
            console.error('获取配置类型失败:', error);
            return GloableResponseItem(ResponseEnum.error, "获取配置类型失败", null);
        }
    }
    
    /**
     * 批量更新配置
     */
    @Auth()
    @ResponseHandler()
    @HttpPut()
    @LogOperation({
        module: "系统配置",
        operationName: "批量更新配置"
    })
    static async batchUpdateSettings(request: ExtendedNextApiRequest) {
        try {
            const data = request.customBody;
            const { settings } = data;
            
            if (!settings || !Array.isArray(settings) || settings.length === 0) {
                return GloableResponseItem(ResponseEnum.fail, "配置数据不能为空", null);
            }
            
            const currentTime = getCurrentTimeInShanghai();
            let totalAffected = 0;
            
            for (const setting of settings) {
                const { id, config_value, is_encrypted } = setting;
                
                let processedValue = config_value;
                
                // 如果需要加密且不是加密标识
                if (is_encrypted === 1 && config_value && config_value !== '***已加密***') {
                    processedValue = SystemSettingController.encryptValue(config_value);
                } else if (config_value === '***已加密***') {
                    // 跳过加密标识的配置
                    continue;
                }
                
                const result = await prisma.$executeRaw(Prisma.sql`
                    UPDATE sys_setting 
                    SET config_value = ${processedValue}, update_time = ${currentTime}
                    WHERE id = ${parseInt(id)}
                `);
                
                totalAffected += Number(result);
            }
            
            return GloableResponseItem(ResponseEnum.success, "批量更新配置成功", { affected: totalAffected });
        } catch (error) {
            console.error('批量更新配置失败:', error);
            return GloableResponseItem(ResponseEnum.error, "批量更新配置失败", null);
        }
    }

    // 重置配置到默认值 
    @Auth()
    @ResponseHandler()
    @HttpPost()
    static async resetSettingToDefault(request: ExtendedNextApiRequest) {
        return GloableResponseItem(ResponseEnum.fail, "该接口暂未开放", null);
    }
    
    /**
     * 加密配置值
     */
    private static encryptValue(value: string): string {
        try {
            const algorithm = 'aes-256-cbc';
            const key = crypto.scryptSync(process.env.ENCRYPTION_KEY || 'default-key', 'salt', 32);
            const iv = crypto.randomBytes(16);
            const cipher = crypto.createCipher(algorithm, key);
            let encrypted = cipher.update(value, 'utf8', 'hex');
            encrypted += cipher.final('hex');
            return `${iv.toString('hex')}:${encrypted}`;
        } catch (error) {
            console.error('加密失败:', error);
            return value;
        }
    }
    
    /**
     * 解密配置值
     */
    private static decryptValue(encryptedValue: string): string {
        try {
            const algorithm = 'aes-256-cbc';
            const key = crypto.scryptSync(process.env.ENCRYPTION_KEY || 'default-key', 'salt', 32);
            const [ivHex, encrypted] = encryptedValue.split(':');
            const iv = Buffer.from(ivHex, 'hex');
            const decipher = crypto.createDecipher(algorithm, key);
            let decrypted = decipher.update(encrypted, 'hex', 'utf8');
            decrypted += decipher.final('utf8');
            return decrypted;
        } catch (error) {
            console.error('解密失败:', error);
            return encryptedValue;
        }
    }
}

// 导出所有HTTP方法的处理函数
export const { GET, POST, PUT, DELETE } = createAllMethodHandlers(SystemSettingController);